/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <unistd.h>
#include "makecard_service.h"
#include "file_ex.h"
#include "system_ability_definition.h"
#include "hilog_wrapper.h"
#include "makecard_errors.h"
#include "makecard_common.h"
#include "cashdevice_status.h"
namespace SwanLink {
namespace Finance {
namespace {
// std::string MAKECARD_SERVICE_NAME = "Makecard_service";
auto pms = DelayedSpSingleton<MakecardService>::GetInstance();
const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(
    pms.GetRefPtr());
}

#define DEFINE_ERR(id, err) {id, err}

const std::map<int, const std::string> g_sErr = {
    DEFINE_ERR(ERR_CARD_JAM, "塞卡"),
    DEFINE_ERR(ERR_REJECT_BOX_OPEN, "废卡箱被打开"),
    DEFINE_ERR(ERR_REJECT_BOX_FULL, "废卡箱满"),
    DEFINE_ERR(ERR_RIBBON_ERROR, "色带错误"),
    DEFINE_ERR(ERR_NO_CARD, "卡机无卡"),
    DEFINE_ERR(ERR_FLIPPER_ERROR, "翻卡模块错误"),
    DEFINE_ERR(ERR_CARD_FEED_ERROR, "传动卡片错误"),
    DEFINE_ERR(ERR_COVER_OPEN, "上盖打开"),
    DEFINE_ERR(ERR_REQUEST_NOT_SUPPORTED, "请求不支持"),
    DEFINE_ERR(ERR_THE_FIRMWARE_COMMAND_NOT_SUPPORTED, "固件命令不支持"),
    DEFINE_ERR(ERR_OPEN_SPECIFIED_DEVICE_OR_FILE_FAILED, "打开指定设备或文件失败"),
    DEFINE_ERR(ERR_FLIPPER_NOT_ATTACHED, "翻卡模块未安装"),
    DEFINE_ERR(ERR_RIBBON_MISSING, "查找不到色带"),
    DEFINE_ERR(ERR_CARD_EJECT_ERROR, "排卡错误"),
    DEFINE_ERR(ERR_CARD_OUT, "卡片用完"),
    DEFINE_ERR(ERR_FILM_OUT, "转印膜用完"),
    DEFINE_ERR(ERR_FILM_ERROR, "转印膜错误"),
    DEFINE_ERR(ERR_FILM_MISSING, "没有放转印膜"),
    DEFINE_ERR(ERR_RIBBON_OUT, "色带用完"),
    DEFINE_ERR(ERR_MAGNETIC_ENCODING_MODULE_NOT_ATTACHED, "未接上磁条模块")
};

MakecardService::MakecardService()
    : SystemAbility(FINANCE_MAKECARD_SERVICE_ID, true),
    ready(false), isBusy(false) {
}

MakecardService::~MakecardService() {
}

void MakecardService::OnDump() {}

void MakecardService::OnStart() {
    MAKECARD_HILOGD(MAKECARD_SRV, "Enter");
    if (ready) {
        MAKECARD_HILOGD(MAKECARD_SRV, "Service is ready, nothing to do");
        return;
    }
    if (!(Init())) {
        MAKECARD_HILOGE(MAKECARD_SRV, "Call init failed");
        return;
    }

    if (!Publish(this)) {
        MAKECARD_HILOGE(MAKECARD_SRV, "Register to system ability manager failed");
        return;
    }
    ready = true;
}

bool MakecardService::Init()
{
    MAKECARD_HILOGD(MAKECARD_SRV, "Enter");
    OnInit(CASH_DEVICE_MAKECARD, "MakeCard");
    AddStatusList(g_sErr);
    MAKECARD_HILOGI(MAKECARD_SRV, "Success");
    return true;
}

void MakecardService::OnStop()
{
    MAKECARD_HILOGW(MAKECARD_SRV, "Enter");
    OnFree();
    MAKECARD_HILOGW(MAKECARD_SRV, "Success");
}

int32_t MakecardService::Dump(int32_t fd, const std::vector<std::u16string> &args)
{
    return ERR_OK;
}


int MakecardService::SetConfig(int handle, int configType, int configValue)
{
    std::shared_ptr<IAdaptor> adaptor = GetAdaptor(handle);
    if (adaptor == nullptr) {
        return HANDLE_INVALID;
    }
    if (isBusy) {
        return ERR_DEVICE_BUSY;
    }
    isBusy = true;
    IMakeCardAdaptor *makeCard = static_cast<IMakeCardAdaptor*>(adaptor.get());
    int ret = makeCard->SetConfig(configType, configValue);
    isBusy = false;
    return ret;
}

int MakecardService::SetStandbyParam(int handle, int dir, int pos, int standbyTime)
{
    std::shared_ptr<IAdaptor> adaptor = GetAdaptor(handle);
    if (adaptor == nullptr) {
        return HANDLE_INVALID;
    }
    if (isBusy) {
        return ERR_DEVICE_BUSY;
    }
    isBusy = true;
    IMakeCardAdaptor *makeCard = static_cast<IMakeCardAdaptor*>(adaptor.get());
    int ret = makeCard->SetStandbyParam(dir, pos, standbyTime);
    isBusy = false;
    return ret;
}

int MakecardService::PrintCard(int handle, BmpInfo cardBmpInfo)
{
    std::shared_ptr<IAdaptor> adaptor = GetAdaptor(handle);
    if (adaptor == nullptr) {
        return HANDLE_INVALID;
    }
    MAKECARD_HILOGE(MAKECARD_SRV, "MakecardService::PrintCard");
    if (isBusy) {
        return ERR_DEVICE_BUSY;
    }
    isBusy = true;
    IMakeCardAdaptor *makeCard = static_cast<IMakeCardAdaptor*>(adaptor.get());
    int ret = makeCard->PrintCard(cardBmpInfo);
    isBusy = false;
    return ret;
}

int MakecardService::GetDeviceInfo(int handle, int infoType, char *infoValue)
{
    std::shared_ptr<IAdaptor> adaptor = GetAdaptor(handle);
    if (adaptor == nullptr) {
        return HANDLE_INVALID;
    }
    if (isBusy) {
        return ERR_DEVICE_BUSY;
    }
    isBusy = true;
    IMakeCardAdaptor *makeCard = static_cast<IMakeCardAdaptor*>(adaptor.get());
    int ret = makeCard->GetDeviceInfo(infoType, infoValue);
    isBusy = false;
    return ret;
}

int MakecardService::GetErrorString(int handle, int status, char* statusDesc)
{
    std::shared_ptr<IAdaptor> adaptor = GetAdaptor(handle);
    if (adaptor == nullptr) {
        return HANDLE_INVALID;
    }

    IMakeCardAdaptor *makeCard = static_cast<IMakeCardAdaptor*>(adaptor.get());
    makeCard->GetErrorString(status, statusDesc);
    return SUCCESS;
}

int MakecardService::MoveCard(int handle, int postionMoveTo)
{
    std::shared_ptr<IAdaptor> adaptor = GetAdaptor(handle);
    if (adaptor == nullptr)
        return HANDLE_INVALID;
    if (isBusy) {
        return ERR_DEVICE_BUSY;
    }
    isBusy = true;
    IMakeCardAdaptor *makeCard = static_cast<IMakeCardAdaptor*>(adaptor.get());
    int ret = makeCard->MoveCard(postionMoveTo);
    isBusy = false;
    return ret;
}

int MakecardService::FlipCard(int handle)
{
    std::shared_ptr<IAdaptor> adaptor = GetAdaptor(handle);
    if (adaptor == nullptr)
        return HANDLE_INVALID;
    if (isBusy) {
        return ERR_DEVICE_BUSY;
    }
    isBusy = true;
    IMakeCardAdaptor *makeCard = static_cast<IMakeCardAdaptor*>(adaptor.get());
    int ret = makeCard->FlipCard();
    isBusy = false;
    return ret;
}
}  // namespace Finance
}  // namespace SwanLink
